package com.wwj.my_ummary.config.exception;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.io.IOException;

/**
 * @Description 全局异常拦截器
 */
//@ControllerAdvice
//@ResponseBody
public class GlobalExceptionHandler {

    private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s";
    private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //运行时异常
    @ExceptionHandler(RuntimeException.class)
    public String runtimeExceptionHandler(RuntimeException ex) {
        log.error("运行时异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(10, "运行时异常，请联系客服处理");
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    public String nullPointerExceptionHandler(NullPointerException ex) {
        log.error("空指针异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(12, "空指针异常: 数据可能为空，请联系客服处理");
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    public String classCastExceptionHandler(ClassCastException ex) {

        log.error("类型转换异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(13, "类型转换异常，请联系客服处理");
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    public String iOExceptionHandler(IOException ex) {
        log.error("IO异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(14, "IO异常，请联系客服处理");
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        log.error("未知方法异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(15, "未知方法异常，请联系客服处理");
    }

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        log.error("数组越界异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(16, "400错误: 请求不可读，请联系客服处理");
    }

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public String requestNotReadable(HttpMessageNotReadableException ex) {
        log.error("400错误: 请求不可读");
        log.error(ex.getLocalizedMessage());
        return resultFormat(17, "400错误: 请求不可读，请联系客服处理");
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    public String requestTypeMismatch(TypeMismatchException ex) {
        log.error("400错误: 类型不匹配异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(18, "400错误: 缺少Servlet请求，请联系客服处理");
    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
        log.error("400错误: 缺少Servlet请求");
        log.error(ex.getLocalizedMessage());
        return resultFormat(19, "400错误: 缺少Servlet请求，请联系客服处理");
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public String request405(HttpRequestMethodNotSupportedException ex) {
        log.error("405错误: Http请求方法不受支持的异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(20, "405错误: Http请求方法不受支持的异常，请联系客服处理");
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public String request406(HttpMediaTypeNotAcceptableException ex) {
        log.error("406错误: Http媒体类型不可接受的异常");
        log.error(ex.getLocalizedMessage());
        return resultFormat(21, "406错误: Http媒体类型不可接受的异常，请联系客服处理");
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public String server500(RuntimeException ex) {
        log.error("500错误: 不支持转换异常,");
        log.error(ex.getLocalizedMessage());
        return resultFormat(22, "500错误: 不支持转换异常，请联系客服处理");
    }

    //栈溢出
    @ExceptionHandler({StackOverflowError.class})
    public String requestStackOverflow(StackOverflowError ex) {
        log.error("栈溢出");
        log.error(ex.getLocalizedMessage());
        return resultFormat(23, "栈溢出，请联系客服处理");
    }

    //除数不能为0
    @ExceptionHandler({ArithmeticException.class})
    public String arithmeticException(ArithmeticException ex) {
        log.error("除数不能为0");
        log.error(ex.getLocalizedMessage());
        return resultFormat(23, "除数不能为0，，请联系客服处理");
    }


    //其他错误
    @ExceptionHandler({Exception.class})
    public String exception(Exception ex) {
        log.error("其他错误");
        log.error(ex.getLocalizedMessage());
        return resultFormat(24, "其他错误，请联系客服处理");
    }

    private <T extends Throwable> String resultFormat(Integer code, String msg) {
        log.error(msg);
        log.error(String.format(logExceptionFormat, code, msg));
        return JsonResult.failed(code, msg);
    }

}